package com.example.ad.sdk.domain.repositories.base

import com.example.ad.sdk.domain.repositories.enums.ApiCode
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.coroutineScope


/**
 * 通用API响应数据封装类
 * 提供了成功和失败的标识、错误代码解析等功能
 * @param T 响应数据的类型
 * @property code 响应状态码
 * @property msg 响应消息
 * @property data 响应数据
 */
data class BaseResponse<out T>(val code: Int, val msg: String, val data: T?){
    /**
     * 判断响应是否成功
     * @return 响应成功返回true，否则返回false
     */
    val isSuccess: Boolean get() = code == ApiCode.SUCCESS.value

    /**
     * 判断响应是否失败
     * @return 响应失败返回true，否则返回false
     */
    val isFailed: Boolean get() = code != ApiCode.SUCCESS.value

    /**
     * 根据响应状态码获取对应的API错误代码枚举
     * @return 对应的ApiCode枚举对象，如果找不到对应枚举则返回null
     */
    val apiCode: ApiCode? get() = ApiCode.Companion.ofValue(code)
}

fun <T: Any> onResponseError(): BaseResponse<T> {
    return BaseResponse(-1, "服务器开小差了，请稍候重试", null)
}

/**
 * 在协程中处理API响应成功的逻辑
 * 如果响应成功，则执行传入的成功处理代码块
 * @param successBlock 成功时执行的代码块，接收响应数据作为参数
 * @return 返回当前的BaseResponse对象
 */
suspend fun <T : Any> BaseResponse<T>.doSuccess(successBlock: (suspend CoroutineScope.(T?) -> Unit)? = null): BaseResponse<T> {
    return coroutineScope {
        if (isSuccess) successBlock?.invoke(this, this@doSuccess.data)
        this@doSuccess
    }
}

/**
 * 在协程中处理API响应失败的逻辑
 * 如果响应失败，则执行传入的失败处理代码块
 * @param errorBlock 失败时执行的代码块，接收响应状态码和消息作为参数
 * @return 返回当前的BaseResponse对象
 */
suspend fun <T : Any> BaseResponse<T>.doError(errorBlock: (suspend CoroutineScope.(Int, String) -> Unit)? = null): BaseResponse<T> {
    return coroutineScope {
        if (isFailed) errorBlock?.invoke(this, this@doError.code, this@doError.msg)
        this@doError
    }
}
